<script setup lang="ts">
import { ref, onMounted } from 'vue'
import type { FormInst, FormItemInst, FormItemRule, FormRules } from 'naive-ui'
import { NForm, NFormItem, NInput, NRow, NCol, NButton, NDynamicInput, NImage, NModal, NIcon } from 'naive-ui'
import { USER_INIT } from "@/service/apis/from";
import { useMessage } from 'naive-ui'
import { useRouter } from 'vue-router';
import { encrypt, getJmg } from '@/service/jmg';
import SvgIcon from '@/components/SvgIcon.vue';
const router = useRouter()
const secret = ref('')

onMounted(() => {
    getJmg((reslut:any) => {
        if(reslut.error){
            message.error("本地加密狗检测失败！")
            router.go(-1)
        }else{
            secret.value = reslut.secret
        }
    })
})
const formRef = ref<FormInst | null>(null)
const rPasswordFormItemRef = ref<FormItemInst | null>(null)
const message = useMessage()
const model = ref<any>({
    face_data: null,
    security_question: [
        {
            key: '',
            value: ''
        },
        {
            key: '',
            value: ''
        },
        {
            key: '',
            value: ''
        }
    ],
    password: null,
    reenteredPassword: null
})
function validatePasswordStartWith(
    rule: FormItemRule,
    value: string
): boolean {
    return (
        !!model.value.password
        && model.value.password.startsWith(value)
        && model.value.password.length >= value.length
    )
}
function validatePasswordSame(rule: FormItemRule, value: string): boolean {
    return value === model.value.password
}
function validateSercurityQuestion() {
    return model.value.security_question.every((item:any) => item.key && item.value)
}
function validatePasswordContent() {
    const { password } = model.value
    // 正则  '至少8位 必须含有大小写字母和数字'
    const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[A-Za-z\d]{8,}$/;
    return regex.test(password);
}
const rules: FormRules = {
    face_data: [
        {
            required: false,
            message: '请设置扫脸照片'
        }
    ],
    security_question: [
        {
            required: true,
            validator: validateSercurityQuestion,
            message: '请设置三个安全问题'
        }
    ],
    password: [
        {
            required: true,
            message: '请输入密码'
        },
        {
            validator: validatePasswordContent,
            message: '至少8位 必须含有大小写字母和数字',
            trigger: ['input', 'blur']
        },
    ],
    reenteredPassword: [
        {
            required: true,
            message: '请再次输入密码',
            trigger: ['input', 'blur']
        },
        {
            validator: validatePasswordStartWith,
            message: '两次密码输入不一致',
            trigger: 'input'
        },
        {
            validator: validatePasswordSame,
            message: '两次密码输入不一致',
            trigger: ['blur', 'password-input']
        }
    ]
}

const videoRef = ref()
const streams = ref()
const myConstraints = ref({
    video: {
        facingMode: "user", // 优先调用前置摄像头
    },
})

const videoOpen = () => {
    showModal.value = true
    navigator.mediaDevices.getUserMedia(myConstraints.value).then(
        (stream) => {
            streams.value = stream
            videoRef.value.srcObject = stream;
            //播放视频
            videoRef.value.play();
        },
        (error) => {
            console.error(error.name || error);
        }
    );
};
const videoClose = () => {
    if (streams.value) {
        streams.value.getTracks().forEach((track: any) => track.stop());
    }
};
const handleShoot = () => {
    let canvas = document.createElement("canvas");
    canvas.width = 400;
    canvas.height = 400;
    const context = canvas.getContext("2d");
    context?.drawImage(videoRef.value, 0, 0, canvas.width, canvas.height);
    model.value.face_data = canvas.toDataURL("image/png", 0.1);
    showModal.value = false
    videoClose()
}

function handlePasswordInput() {
    if (model.value.reenteredPassword) {
        rPasswordFormItemRef.value?.validate({ trigger: 'password-input' })
    }
}

function handleValidateButtonClick(e: MouseEvent) {
    e.preventDefault()
    formRef.value?.validate((errors) => {
        if (!errors) {
            const { face_data, security_question, password } = model.value
            let data = {
                face_data,
                security_question,
                encryptedPassword: encrypt(password, secret.value),
            }

            USER_INIT({ "params": JSON.stringify(data) }).then((res: any) => {
                if (res.stacode == 200) {
                    console.log('修改成功', res)
                    message.success('设置成功')
                    setTimeout(() => {
                        router.go(-1)
                    }, 1200)
                }
                else {
                    message.error(res.message)
                }
            }).catch((err: any) => {
                console.log('err', err);
            })

        }
        else {
            console.log(errors)
            message.error('验证失败')
        }
    })
}

const showModal = ref(false)
</script>
<template>
    <n-modal v-model:show="showModal" preset="card" style="width: 600px" title="拍一张脸部照片" v-on:close="videoClose">
        <div class="rl_video">
            <div class="rl_video_ladding">
                <video ref="videoRef" class="rl_video_ladding_video"></video>
            </div>
        </div>
        <n-button type="primary" attr-type="button" @click="handleShoot">拍照</n-button>
    </n-modal>
    <n-form ref="formRef" :model="model" :rules="rules">
        <n-form-item path="password" label="新密码">
            <n-input v-model:value="model.password" type="password" @input="handlePasswordInput"
                placeholder="输入新密码(至少8位 必须含有大小写字母和数字)" @keydown.enter.prevent maxlength="16" show-count />
        </n-form-item>
        <n-form-item ref="rPasswordFormItemRef" first path="reenteredPassword" label="重复密码">
            <n-input v-model:value="model.reenteredPassword" :disabled="!model.password" type="password"
                placeholder="再次输入新密码" @keydown.enter.prevent maxlength="16" show-count />
        </n-form-item>
        <n-form-item path="security_question" label="安全问题">
            <n-dynamic-input v-model:value="model.security_question" preset="pair" key-placeholder="设置安全问题"
                value-placeholder="答案" :min="3" :max="3"><template
                    #action="{ index, create, remove, move }"><span></span></template></n-dynamic-input>
        </n-form-item>
        <n-form-item label="扫脸照片">
            <div v-if="model.face_data" style="margin-right: 10px;">
                <n-image width="75" :src="model.face_data" />
            </div>
            <n-button v-if="model.face_data" style="margin-right: 10px;" attr-type="button"
                @click="model.face_data = undefined">
                <n-icon>
                    <SvgIcon iconClass="guanbi1"></SvgIcon>
                </n-icon>
            </n-button>
            <n-button type="primary" attr-type="button" @click="videoOpen">{{model.face_data ? '重拍' : '打开摄像头'}}</n-button>
        </n-form-item>

        <n-row :gutter="[0, 24]">
            <n-col :span="24">
                <div style="display: flex; justify-content: flex-end">
                    <n-button :disabled="model.age === null" round type="primary" @click="handleValidateButtonClick">
                        提交
                    </n-button>
                </div>
            </n-col>
        </n-row>
    </n-form>
</template>
<style scoped>
.rl_video {
    /* width: 400px; */
    height: 270px;
    border-radius: 50%;
    /*background-color: rgb(38, 57, 57);*/
    position: relative;
}

.rl_video_ladding {
    width: 260px;
    height: 260px;
    border-radius: 50%;
    background-color: rgb(38, 57, 57);
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    background: white;
    animation: changeBg 5s infinite;
    position: relative;
}

.rl_video_ladding_video {
    width: 250px;
    height: 250px;
    border-radius: 50%;
    object-fit: cover;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);

}
</style>